#include "agcTree.h"

#include <QSet>
#include <QMenu>
#include <QAction>
#include <QAbstractItemModel>
#include <QMouseEvent>
#include <QHeaderView>
#include <QMessageBox>
#include <QDebug>

#include "Editor/treemodel.hpp"
#include "Data/realtimedata.hpp"
#include "Item/FileQt.h"
#include "Data/datastruct.hpp"
#include "Editor/delegate.h"
#include "AGCDefDialog.h"
#include "AGCProDialog.h"

AGCTreeView::AGCTreeView(QAbstractItemModel * model,QWidget * parent)
    : QTreeView(parent)
    , modify(false)
{
	this->setModel (model);
	win_init();
};

AGCTreeView::~AGCTreeView()
{

};

void AGCTreeView::win_init()
{
    // this->setMouseTracking(true);
    this->setTextElideMode(Qt::ElideRight);//...display at the end of the text.
    // this->setCornerButtonEnabled(true);
    // this->setSelectionBehavior(QAbstractItemView::SelectRows);
    this->setSelectionMode(QAbstractItemView::ExtendedSelection);

	this->setColumnHidden(1,true);
    this->setColumnHidden(2,true);
    this->setColumnHidden(3,true);

	this->header()->hide();
};

void AGCTreeView::clear()
{
    this->clearTree();
};

void AGCTreeView::createAgcTree(QString _cz,QList<AGCDefItem> _agcdefs,QList<AGCProtem> _agcpros)
{
    cz_agcdefs.clear();
    cz_agcpros.clear();
    clearTree();
    cz_agcpros = _agcpros;

    TreeModel *model = qobject_cast<TreeModel *>(this->model());
	QStringList _parentL;
	QVector<QVariant> Data;
	Data << QVariant(_cz);
    model->insertItem(_parentL, Data);
    for (QList<AGCDefItem>::iterator it = _agcdefs.begin();
			it != _agcdefs.end(); it++)
    {
        cz_agcdefs.append(*it);
        // qDebug()<<QString("ID:%1,Desc:%2,YTINDEX:%3\n")
        //     .arg((*it).ID)
        //     .arg((*it).Description)
        //     .arg((*it).YTIndex);
        _parentL<<_cz;
        Data.clear();
        Data << QVariant((*it).Description)
            << QVariant(-1) << QVariant((*it).ID) << QVariant(-1);
        model->insertItem(_parentL,Data);

        _parentL<<(*it).Description;
        Data.clear();
        Data << QVariant((*it).YTName)
            << QVariant(-1) << QVariant((*it).ID) << QVariant(0);
        model->insertItem(_parentL,Data);

        Data.clear();
        Data << QVariant((*it).YCName)
            << QVariant(-1) << QVariant((*it).ID) << QVariant(1);
        model->insertItem(_parentL,Data);
        _parentL.clear();
    }
    this->expandAll();
};

void AGCTreeView::setModify(bool _f)
{
    modify = _f;
};

void AGCTreeView::clearTree()
{
    try{
        QAbstractItemModel *model = this->model();
        int count = model->rowCount();
        if(count>0)
            model->removeRows (0,count);
        this->update();
    }catch(QString exception){
        QMessageBox::about(this,tr("exception Error"),exception);
    }
};

void AGCTreeView::contextMenuEvent ( QContextMenuEvent * event )
{
    if (modify)
    {
        if(indexAt(event->pos()).isValid()){
            QModelIndex _index = indexAt(event->pos());
            int _level = 1;
            QModelIndex _pIndex = _index.parent();
            while(QModelIndex()!=_pIndex)
            {
                _pIndex = _pIndex.parent();
                _level+=1;
            }
            QMenu menu;
            if (1==_level)
            {
                QAction *insertChildAction = menu.addAction(tr("createAgc"));
                connect(insertChildAction, SIGNAL(triggered()), this, SLOT(createAgc()));
                QAction *createAgcProAction = menu.addAction(tr("createAgcPro"));
                connect(createAgcProAction, SIGNAL(triggered()), this, SLOT(createAgcPro()));
                menu.addSeparator();
                QAction *saveAGCDefAction = menu.addAction(tr("saveAGCDef"));
                connect(saveAGCDefAction, SIGNAL(triggered()), this, SLOT(saveAGCDef()));
            }
            if (2==_level)
            {
                QAction *removeRowAction = menu.addAction(tr("removeAGCDef"));
                connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeAGCDef()));
            }
            menu.exec(event->globalPos());
        }
    }

    QTreeView::contextMenuEvent(event);
};

void AGCTreeView::mousePressEvent ( QMouseEvent * event )
{
    if(!indexAt(event->pos()).isValid())
    {
        this->setCurrentIndex(QModelIndex());
    }
    QTreeView::mousePressEvent(event);
};

void AGCTreeView::mouseDoubleClickEvent ( QMouseEvent * event )
{
	QModelIndex _index = indexAt(event->pos());
	// qDebug() << _index.data().toString()<<"\n";
    if(_index.isValid())
    {
        TreeModel *model = qobject_cast<TreeModel *>(this->model());
        QVector<DrawDef> _drawdefs;
        if(_index.parent()==QModelIndex()){
            for (int id = 0; id < model->rowCount(_index); ++id)
            {
                QModelIndex _index_agc = model->index(id,0,_index);
                for (int i = 0; i < model->rowCount(_index_agc); ++i)
                {
                    /* code */
                    DrawDef _drawdef;
                    _drawdef.name = model->index(i,0,_index_agc).data().toString();
                    _drawdef.pid = model->index(i,1,_index_agc).data().toInt();
                    _drawdef.idx = model->index(i,2,_index_agc).data().toInt();
                    _drawdef.tid = model->index(i,3,_index_agc).data().toInt();
                    _drawdefs.append(_drawdef);
                }
            }
        }else if(_index.parent().parent()==QModelIndex())
        {
            for (int i = 0; i < model->rowCount(_index); ++i)
            {
                /* code */
                DrawDef _drawdef;
                _drawdef.name = model->index(i,0,_index).data().toString();
                _drawdef.pid = model->index(i,1,_index).data().toInt();
                _drawdef.idx = model->index(i,2,_index).data().toInt();
                _drawdef.tid = model->index(i,3,_index).data().toInt();
                _drawdefs.append(_drawdef);
            }
        }else{
            DrawDef _drawdef;
            _drawdef.name = model->index(_index.row(),0,_index.parent()).data().toString();
            _drawdef.pid = model->index(_index.row(),1,_index.parent()).data().toInt();
            _drawdef.idx = model->index(_index.row(),2,_index.parent()).data().toInt();
            _drawdef.tid = model->index(_index.row(),3,_index.parent()).data().toInt();
            _drawdefs.append(_drawdef);
        }
        emit itemDoubleClick(_drawdefs);
    }
    // QTreeView::mouseDoubleClickEvent(event);
};

void AGCTreeView::removeAGCDef()
{
    QModelIndex index = this->selectionModel()->currentIndex();
    TreeModel *model = qobject_cast<TreeModel *>(this->model());
    for (QList<AGCDefItem>::iterator it = cz_agcdefs.begin();it != cz_agcdefs.end();it++)
    {
        if ((*it).Description==index.data().toString())
        {
            it = cz_agcdefs.erase(it);
        }
    }
    if (model->removeRow(index.row(), index.parent()))
        updateActions();
};

void AGCTreeView::removeRow()
{
    QModelIndex index = this->selectionModel()->currentIndex();
    QAbstractItemModel *model = this->model();
    if (model->removeRow(index.row(), index.parent()))
        updateActions();
};

void AGCTreeView::updateActions()
{
    bool hasCurrent = this->selectionModel()->currentIndex().isValid();
    if (hasCurrent) {
        this->closePersistentEditor(this->selectionModel()->currentIndex());
    }
};

void AGCTreeView::createAgc()
{
    QSet<int> _agcid_exist;
    for (QList<AGCDefItem>::iterator it = cz_agcdefs.begin();it != cz_agcdefs.end();it++)
    {
        _agcid_exist.insert((*it).ID);
    }
    AGCDefDialog *ptr_AGCDefDialog= new AGCDefDialog(_agcid_exist,this);
    qRegisterMetaType<AGCDefItem>("AGCDefItem");
    connect(ptr_AGCDefDialog,SIGNAL(createItem(AGCDefItem))
        ,this,SLOT(createItem(AGCDefItem)));
    ptr_AGCDefDialog->show();
};

void AGCTreeView::createItem(AGCDefItem defItem)
{
    for (QList<AGCDefItem>::iterator it = cz_agcdefs.begin();it != cz_agcdefs.end();it++)
    {
        if ((*it).Description==defItem.Description)
        {
            QMessageBox::warning(this, tr("AGC node create"),
                tr("agc_desc(%1) has been exist, please reset it.")
                .arg(defItem.Description));
            return;
        }
    }
    cz_agcdefs.append(defItem);
    TreeModel *model = qobject_cast<TreeModel *>(this->model());
    QModelIndex index = model->index(0,0);
    if (QModelIndex()==index)
    {
        return;
    }
    QStringList _parentL;
    _parentL<<index.data().toString();
    QVector<QVariant> Data;
    Data << QVariant(defItem.Description)
        << QVariant(-1) << QVariant(defItem.ID) << QVariant(-1);
    model->insertItem(_parentL,Data);

    _parentL<<defItem.Description;
    Data.clear();
    Data << QVariant(defItem.YTName)
        << QVariant(-1) << QVariant(defItem.ID) << QVariant(0);
    model->insertItem(_parentL,Data);

    Data.clear();
    Data << QVariant(defItem.YCName)
        << QVariant(-1) << QVariant(defItem.ID) << QVariant(1);
    model->insertItem(_parentL,Data);
};

void AGCTreeView::createAgcPro()
{
    AGCProDialog *ptr_AGCProDialog= new AGCProDialog(cz_agcpros,this);
    qRegisterMetaType<QList<AGCProtem> >("QList<AGCProtem>");
    connect(ptr_AGCProDialog,SIGNAL(createAgcProList(QList<AGCProtem>))
        ,this,SLOT(createAgcProList(QList<AGCProtem>)));
    ptr_AGCProDialog->show();
};

void AGCTreeView::createAgcProList(QList<AGCProtem> _agcpros)
{
    cz_agcpros.clear();
    cz_agcpros = _agcpros;
}

void AGCTreeView::saveAGCDef()
{
    emit saveAGCDefForNewFile(cz_agcdefs,cz_agcpros);
}
